import { defineStore } from 'pinia'
import { useUserStore } from './user'
import { groupSend } from '@/service/edu/group'
import { MESSAGE_STATUS, MESSAGE_TYPE } from '@/utils/enums'

export interface Message {
  id: number
  tmpId?: string
  sendId: string
  recvId?: string
  groupId?: string
  content: string
  type: number
  status: number
  sendTime: number
  selfSend: boolean
  atUserIds?: number[]
  loadStatus?: string
}

export interface Chat {
  targetId: string | number
  type: 'GROUP' | 'PRIVATE'
  name?: string
  showName: string
  headImage: string
  lastContent: string
  lastSendTime: number
  unreadCount: number
  messages: Message[]
  atMe: boolean
  atAll: boolean
  stored: boolean
  delete?: boolean
  sendNickName?: string
  lastTimeTip?: number
}

let cacheChats: Chat[] = []

export const useChatStore = defineStore(
  'chat',
  () => {
    const chats = ref<Chat[]>([])
    const privateMsgMaxId = ref(0)
    const groupMsgMaxId = ref(0)
    const loadingPrivateMsg = ref(false)
    const loadingGroupMsg = ref(false)

    const isLoading = computed(() => loadingPrivateMsg.value || loadingGroupMsg.value)

    const curChats = computed(() => {
      if (cacheChats && isLoading.value) {
        return cacheChats
      }
      return chats.value
    })

    function findChatIdx(chat: Chat): number {
      for (const idx in curChats.value) {
        if (
          curChats.value[idx].type === chat.type &&
          curChats.value[idx].targetId === chat.targetId
        ) {
          return Number(idx)
        }
      }
      return -1
    }

    function findChat(msgInfo: Message): Chat | null {
      const type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'
      const targetId = msgInfo.groupId
        ? msgInfo.groupId
        : msgInfo.selfSend
          ? msgInfo.recvId
          : msgInfo.sendId

      return curChats.value.find((chat) => chat.type === type && chat.targetId === targetId) || null
    }

    function findChatByFriend(fid: string | number): Chat | undefined {
      return curChats.value.find((chat) => chat.type === 'PRIVATE' && chat.targetId === fid)
    }

    function findChatByGroup(gid: string | number): Chat | undefined {
      return curChats.value.find((chat) => chat.type === 'GROUP' && chat.targetId === gid)
    }

    function findMessage(chat: Chat | null, msgInfo: Message): Message | null {
      if (!chat) return null

      return (
        chat.messages.find((msg) => {
          if (msgInfo.id && msg.id === msgInfo.id) return true
          if (msgInfo.tmpId && msg.tmpId && msg.tmpId === msgInfo.tmpId) return true
          return false
        }) || null
      )
    }

    function initChats(chatsData: any) {
      cacheChats = []
      chats.value = []

      for (const chat of chatsData.chats) {
        chat.stored = false
        cacheChats.push(JSON.parse(JSON.stringify(chat)))
        if (chats.value.length < 15) {
          chats.value.push(chat)
        }
      }

      privateMsgMaxId.value = chatsData.privateMsgMaxId || 0
      groupMsgMaxId.value = chatsData.groupMsgMaxId || 0

      cacheChats.forEach((chat) => {
        chat.messages.forEach((msg) => {
          if (msg.loadStatus === 'loading') {
            msg.loadStatus = 'fail'
          }
        })
      })
    }

    function saveToStorage() {
      if (isLoading.value) return

      const userStore = useUserStore()
      const userId = userStore.userInfo?.userId
      const key = `chats-app-${userId}`
      const chatKeys: string[] = []

      chats.value.forEach((chat) => {
        const chatKey = `${key}-${chat.type}-${chat.targetId}`
        if (!chat.stored) {
          if (chat.delete) {
            uni.removeStorageSync(chatKey)
          } else {
            uni.setStorageSync(chatKey, chat)
          }
          chat.stored = true
        }
        if (!chat.delete) {
          chatKeys.push(chatKey)
        }
      })

      const chatsData = {
        privateMsgMaxId: privateMsgMaxId.value,
        groupMsgMaxId: groupMsgMaxId.value,
        chatKeys,
      }

      uni.setStorageSync(key, chatsData)
      chats.value = chats.value.filter((chat) => !chat.delete)
    }

    function clear() {
      cacheChats = []
      chats.value = []
      privateMsgMaxId.value = 0
      groupMsgMaxId.value = 0
      loadingPrivateMsg.value = false
      loadingGroupMsg.value = false
    }

    function loadChat() {
      return new Promise((resolve, reject) => {
        const userStore = useUserStore()
        const userId = userStore.userInfo?.userId
        const chatsData = uni.getStorageSync('chats-app-' + userId)
        if (chatsData) {
          if (chatsData.chatKeys) {
            const time = new Date().getTime()
            chatsData.chats = []
            chatsData.chatKeys.forEach((key) => {
              const chat = uni.getStorageSync(key)
              if (chat) {
                chatsData.chats.push(chat)
              }
            })
          }
          initChats(chatsData)
        }
        resolve({})
      })
    }

    function sendMessage(msgInfo: Message) {
      return new Promise((resolve, reject) => {
        // 生成临时消息ID
        msgInfo.tmpId = generateTmpId()
        msgInfo.sendTime = new Date().getTime()
        msgInfo.status = 0 // 未发送
        msgInfo.selfSend = true
        // 先插入消息到本地
        insertMessage(msgInfo)

        // 发送消息到服务器
        groupSend(msgInfo)
          .then((res) => {
            if (res.code === 200) {
              // 更新消息状态
              msgInfo.id = res.data?.id
              msgInfo.status = 1 // 已发送
              updateMessage(msgInfo)
              resolve(res.data)
            } else {
              msgInfo.status = -1 // 发送失败
              updateMessage(msgInfo)
              reject(new Error(res.msg))
            }
          })
          .catch((err) => {
            msgInfo.status = -1 // 发送失败
            updateMessage(msgInfo)
            reject(err)
          })
      })
    }

    function insertMessage(msgInfo: Message) {
      // 获取对方id或群id
      const type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'
      // 记录消息的最大id
      if (msgInfo.id && type == 'PRIVATE' && msgInfo.id > privateMsgMaxId.value) {
        privateMsgMaxId.value = msgInfo.id
      }
      if (msgInfo.id && type == 'GROUP' && msgInfo.id > groupMsgMaxId.value) {
        groupMsgMaxId.value = msgInfo.id
      }
      const chat = findChat(msgInfo)
      const message = findMessage(chat, msgInfo)
      if (message) {
        Object.assign(message, msgInfo)
        // 撤回消息需要显示
        if (msgInfo.type == MESSAGE_TYPE.RECALL) {
          chat.lastContent = msgInfo.content
        }
        chat.stored = false
        saveToStorage()
        return
      }
      // 会话列表内容
      if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
        chat.lastContent = '[图片]'
      } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
        chat.lastContent = '[文件]'
      } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
        chat.lastContent = '[语音]'
      } else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VOICE) {
        chat.lastContent = '[语音通话]'
      } else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VIDEO) {
        chat.lastContent = '[视频通话]'
      } else if (
        msgInfo.type == MESSAGE_TYPE.TEXT ||
        msgInfo.type == MESSAGE_TYPE.RECALL ||
        msgInfo.type == MESSAGE_TYPE.TIP_TEXT
      ) {
        chat.lastContent = msgInfo.content
      }
      chat.lastSendTime = msgInfo.sendTime
      chat.sendNickName = msgInfo.sendNickName

      // 未读加1
      if (
        !msgInfo.selfSend &&
        msgInfo.status != MESSAGE_STATUS.READED &&
        msgInfo.type != MESSAGE_TYPE.TIP_TEXT
      ) {
        chat.unreadCount++
      }

      // 是否有人@我
      if (
        !msgInfo.selfSend &&
        chat.type == 'GROUP' &&
        msgInfo.atUserIds &&
        msgInfo.status != MESSAGE_STATUS.READED
      ) {
        const userStore = useUserStore()
        const userId = userStore.userInfo.id
        if (msgInfo.atUserIds.indexOf(userId) >= 0) {
          chat.atMe = true
        }
        if (msgInfo.atUserIds.indexOf(-1) >= 0) {
          chat.atAll = true
        }
      }

      // 间隔大于10分钟插入时间显示
      if (!chat.lastTimeTip || chat.lastTimeTip < msgInfo.sendTime - 600 * 1000) {
        chat.messages.push({
          sendTime: msgInfo.sendTime,
          type: MESSAGE_TYPE.TIP_TIME,
        })
        chat.lastTimeTip = msgInfo.sendTime
      }

      // 根据id顺序插入，防止消息乱序
      const insertPos = chat.messages.length
      // // 防止 图片、文件 在发送方 显示 在顶端  因为还没存库，id=0
      // if (msgInfo.id && msgInfo.id > 0) {
      //   for (const idx in chat.messages) {
      //     if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) {
      //       insertPos = idx
      //       console.log(`消息出现乱序,位置:${chat.messages.length},修正至:${insertPos}`)
      //       break
      //     }
      //   }
      // }

      if (insertPos == chat.messages.length) {
        // 这种赋值效率最高
        chat.messages[insertPos] = msgInfo
      } else {
        chat.messages.splice(insertPos, 0, msgInfo)
      }
      chat.stored = false
      saveToStorage()

      // if (chat) {
      //   chat.messages.push(msgInfo)
      //   chat.lastContent = getLastContent(msgInfo)
      //   chat.lastSendTime = msgInfo.sendTime
      //   saveToStorage()
      // }
    }

    function updateMessage(msgInfo: Message) {
      const chat = findChat(msgInfo)
      if (chat) {
        const idx = chat.messages.findIndex((msg) => msg.tmpId === msgInfo.tmpId)
        if (idx > -1) {
          chat.messages[idx] = msgInfo
          saveToStorage()
        }
      }
    }

    function getLastContent(msgInfo: Message): string {
      switch (msgInfo.type) {
        case 0: // 文本
          return msgInfo.content
        case 1: // 图片
          return '[图片]'
        case 2: // 文件
          return '[文件]'
        default:
          return msgInfo.content
      }
    }

    function generateTmpId(): string {
      return `tmp_${Date.now()}_${Math.random().toString(36).slice(2)}`
    }

    function refreshChats() {
      if (!cacheChats) {
        return
      }
      // 排序
      cacheChats.sort((chat1, chat2) => {
        return chat2.lastSendTime - chat1.lastSendTime
      })
      // 将消息一次性装载回来
      chats.value = cacheChats
      // 清空缓存，不再使用
      cacheChats = null
      saveToStorage()
    }

    function setLoadingGroupMsg(loading) {
      loadingGroupMsg.value = loading
      if (!isLoading.value) {
        refreshChats()
      }
    }

    function openChat(chatInfo) {
      const chats = curChats.value
      let chat = null
      for (const idx in chats) {
        if (chats[idx].type === chatInfo.type && chats[idx].targetId === chatInfo.targetId) {
          chat = chats[idx]
          // 放置头部
          moveTop(idx)
          break
        }
      }
      // 创建会话
      if (chat == null) {
        chat = {
          targetId: chatInfo.targetId,
          type: chatInfo.type,
          showName: chatInfo.showName,
          headImage: chatInfo.headImage,
          lastContent: '',
          lastSendTime: new Date().getTime(),
          unreadCount: 0,
          messages: [],
          atMe: false,
          atAll: false,
          stored: false,
        }
        chats.unshift(chat)
        saveToStorage()
      }
    }
    function activeChat(idx) {
      const chats = curChats.value
      if (idx >= 0) {
        chats[idx].unreadCount = 0
      }
    }

    function resetUnreadCount(chatInfo) {
      const chats = curChats.value
      for (const idx in chats) {
        if (chats[idx].type == chatInfo.type && chats[idx].targetId == chatInfo.targetId) {
          chats[idx].unreadCount = 0
          chats[idx].atMe = false
          chats[idx].atAll = false
          chats[idx].stored = false
          saveToStorage()
        }
      }
    }

    function readedMessage(pos) {
      const chat = findChatByFriend(pos.friendId)
      chat.messages.forEach((m) => {
        if (m.id && m.selfSend && m.status < MESSAGE_STATUS.RECALL) {
          // pos.maxId为空表示整个会话已读
          if (!pos.maxId || m.id <= pos.maxId) {
            m.status = MESSAGE_STATUS.READED
            chat.stored = false
          }
        }
      })
      if (!chat.stored) {
        saveToStorage()
      }
    }

    function removeChat(idx) {
      const chats = curChats.value
      chats[idx].delete = true
      chats[idx].stored = false
      saveToStorage()
    }

    function removePrivateChat(userId) {
      const chats = curChats.value
      for (const idx in chats) {
        if (chats[idx].type == 'PRIVATE' && chats[idx].targetId == userId) {
          removeChat(idx)
        }
      }
    }

    function removeGroupChat(groupId) {
      const chats = curChats.value
      for (const idx in chats) {
        if (chats[idx].type == 'GROUP' && chats[idx].targetId == groupId) {
          removeChat(idx)
        }
      }
    }

    function moveTop(idx) {
      if (isLoading.value) {
        return
      }
      const chats = curChats.value
      if (idx > 0) {
        const chat = chats[idx]
        chats.splice(idx, 1)
        chats.unshift(chat)
        chat.lastSendTime = new Date().getTime()
        chat.stored = false
        saveToStorage()
      }
    }

    function deleteMessage(msgInfo) {
      // 获取对方id或群id
      const chat = findChat(msgInfo)
      for (const idx in chat.messages) {
        // 已经发送成功的，根据id删除
        if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
          chat.messages.splice(idx, 1)
          break
        }
        // 正在发送中的消息可能没有id，根据发送时间删除
        if (
          msgInfo.selfSend &&
          chat.messages[idx].selfSend &&
          chat.messages[idx].sendTime == msgInfo.sendTime
        ) {
          chat.messages.splice(idx, 1)
          break
        }
      }
      chat.stored = false
      saveToStorage()
    }

    function updateChatFromFriend(friend) {
      const chat = findChatByFriend(friend.id)
      if (chat && (chat.headImage != friend.headImageThumb || chat.showName != friend.nickName)) {
        // 更新会话中的群名和头像
        chat.headImage = friend.headImageThumb
        chat.showName = friend.nickName
        chat.stored = false
        saveToStorage()
      }
    }

    function updateChatFromGroup(group) {
      const chat = findChatByGroup(group.id)
      if (chat && (chat.headImage != group.headImageThumb || chat.showName != group.name)) {
        // 更新会话中的群名称和头像
        chat.headImage = group.headImageThumb
        chat.showName = group.name
        chat.stored = false
        saveToStorage()
      }
    }

    function setLoadingPrivateMsg(loading) {
      loadingPrivateMsg.value = loading
      if (!isLoading.value) {
        refreshChats()
      }
    }
    function sortChatGroup() {
      // 排序
      chats.value.sort((chat1, chat2) => {
        return chat2.lastSendTime - chat1.lastSendTime
      })
    }

    return {
      chats,
      privateMsgMaxId,
      groupMsgMaxId,
      loadingPrivateMsg,
      loadingGroupMsg,
      isLoading,
      curChats,
      findChatIdx,
      findChat,
      findChatByFriend,
      findChatByGroup,
      findMessage,
      initChats,
      saveToStorage,
      clear,
      loadChat,
      sendMessage,
      insertMessage,
      updateMessage,
      refreshChats,
      setLoadingPrivateMsg,
      updateChatFromFriend,
      updateChatFromGroup,
      deleteMessage,
      removeGroupChat,
      removePrivateChat,
      resetUnreadCount,
      activeChat,
      setLoadingGroupMsg,
      openChat,
      readedMessage,
      sortChatGroup,
    }
  },
  {
    persist: true,
  },
)
